import {DockerRepositoryInfo, parseDockerRepositoryInfo} from "../src/setup";
// @ts-ignore
import {setup} from '../src/setup';
import * as sinon from 'sinon';
import {expect} from 'chai'
import * as step from '@flow-step/step-toolkit';


describe('parseDockerRepositoryInfo', () => {
    it('should parse ACR repository correctly', () => {
        const dockerRepository = 'registry-vpc.cn-hangzhou.aliyuncs.com';
        const result = parseDockerRepositoryInfo(dockerRepository);
        expect(result.type).to.equal('acr');
        expect(result.region).to.equal('cn-hangzhou');
    });

    it('should parse new ACR personal repository correctly', () => {
        const dockerRepository = 'crpi-3ixfhqbc23r7bca7.cn-hangzhou.personal.cr.aliyuncs.com';
        const result = parseDockerRepositoryInfo(dockerRepository);
        expect(result.type).to.equal('acr');
        expect(result.region).to.equal('cn-hangzhou');
    });

    it('should parse new ACR personal repository vpc address correctly', () => {
        const dockerRepository = 'crpi-xfr8yd0dp00unudu-vpc.cn-hangzhou.personal.cr.aliyuncs.com';
        const result = parseDockerRepositoryInfo(dockerRepository);
        expect(result.type).to.equal('acr');
        expect(result.region).to.equal('cn-hangzhou');
    });

    it('should parse ACR-EE repository correctly', () => {
        const dockerRepository = 'build-steps-public-registry.cn-beijing.cr.aliyuncs.com';
        const result = parseDockerRepositoryInfo(dockerRepository);
        expect(result.type).to.equal('acree');
        expect(result.region).to.equal('cn-beijing');
        expect(result.instance).to.equal('build-steps-public');
    });

    it('should throw error for unknown repository type', () => {
        const dockerRepository = 'unknown-repository';
        expect(() => parseDockerRepositoryInfo(dockerRepository)).to.throw(`Unknown repository type ${dockerRepository}`);
    });
});

describe('setup acr type', () => {
    let sandbox: sinon.SinonSandbox;
    let execCallStub: sinon.SinonStub;

    beforeEach(() => {
        sandbox = sinon.createSandbox();
        execCallStub = sandbox.stub(step.exec, 'call').resolves(0);
        sandbox.stub(process, 'env').value({
            SERVICE_CONNECTION_ID: 'my-service-connection-id',
            FLOW_JOB_TOKEN: 'my-flow-job-token'
        });
    });

    afterEach(() => {
        sandbox.restore();
    });

    it('should handle ACR login correctly', async () => {
        const dockerRepository = 'registry.cn-hangzhou.aliyuncs.com';
        const dockerACRPersonalCertificate = {
            username: 'my-username',
            password: 'my-password'
        };

        const getDockerAcrPersonalCertificateStub = sandbox.stub(step.certificate, 'getDockerAcrPersonalCertificate');
        getDockerAcrPersonalCertificateStub.resolves(dockerACRPersonalCertificate);

        await setup(dockerRepository);

        sinon.assert.calledWith(getDockerAcrPersonalCertificateStub, 'my-flow-job-token', 'my-service-connection-id', 'cn-hangzhou')
        sinon.assert.calledWith(execCallStub, 'docker', ['login', '-u', 'my-username', '-p', 'my-password', dockerRepository])
    });
});

describe('setup acree type', () => {
    let sandbox: sinon.SinonSandbox;
    let execCallStub: sinon.SinonStub;

    beforeEach(() => {
        sandbox = sinon.createSandbox();
        execCallStub = sandbox.stub(step.exec, 'call').resolves(0);
        sandbox.stub(process, 'env').value({
            SERVICE_CONNECTION_ID: 'my-service-connection-id',
            FLOW_JOB_TOKEN: 'my-flow-job-token'
        });
    });

    afterEach(() => {
        sandbox.restore();
    });

    it('should handle ACREE login correctly', async () => {
        const dockerRepository = 'test-registry.cn-shanghai.cr.aliyuncs.com';
        const dockerACREECertificate = {
            username: 'my-acree-username',
            password: 'my-acree-password'
        };

        const getDockerAcrEnterpriseCertificateStub = sandbox.stub(step.certificate, 'getDockerAcrEnterpriseCertificate');
        getDockerAcrEnterpriseCertificateStub.resolves(dockerACREECertificate);

        await setup(dockerRepository);

        sinon.assert.calledWith(getDockerAcrEnterpriseCertificateStub, 'my-flow-job-token', 'my-service-connection-id', 'cn-shanghai', 'test');
        sinon.assert.calledWith(execCallStub, 'docker', ['login', '-u', 'my-acree-username', '-p', 'my-acree-password', dockerRepository]);
    });
});